using FileStorageCenter.Converters;
using FileStorageCenter.EFCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.IdentityModel.Logging;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddHttpContextAccessor();
builder.Services.AddControllers()
    .AddJsonOptions(options => options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);
builder.Services.AddEndpointsApiExplorer();

builder.Services.AddApplicationServices();
builder.Services.AddDataContext(builder.Configuration);

builder.Services.Configure<KestrelServerOptions>(opts =>
{
    opts.Limits.MaxRequestBodySize = long.MaxValue;
});

builder.Services.Configure<JsonOptions>(options =>
{
    options.JsonSerializerOptions.Converters.Add(new TimeOnlyJsonConverter());
    options.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter());
});

TypeDescriptor.AddAttributes(typeof(TimeOnly), new TypeConverterAttribute(typeof(TimeOnlyTypeConverter)));
TypeDescriptor.AddAttributes(typeof(DateOnly), new TypeConverterAttribute(typeof(DateOnlyTypeConverter)));

builder.Services.AddDistributedFileStorage(builder.Configuration);

builder.Services.AddAuthentication(opts =>
{
    opts.DefaultAuthenticateScheme = "Default";
    opts.DefaultChallengeScheme = "Default";
}).AddScheme<DefaultAuthenticationOptions, DefaultAuthenticationHandlerPlatform>("Default", opts => { });

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer("External:IdSrv", opts =>
    {
        opts.BackchannelHttpHandler = new HttpClientHandler()
        {
            ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
        };
        opts.Authority = builder.Configuration["IdentityServer:Authority"];
        opts.RequireHttpsMetadata = !string.IsNullOrWhiteSpace(opts.Authority) &&
            opts.Authority.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
        opts.TokenValidationParameters.ValidateAudience = false;
        opts.SaveToken = true;
        opts.IncludeErrorDetails = true;

        IdentityModelEventSource.ShowPII = true;
    });

builder.Services.AddAuthorization(opts =>
{
    opts.AddPolicy("fsc", policyBuilder =>
    {
        policyBuilder.RequireAuthenticatedUser();
    });
});

var app = builder.Build();

app.Services.Initialize();
app.Services.TryMigrateDatabase();

app.UseCors(options =>
{
    options.AllowAnyHeader();
    options.AllowAnyMethod();
    options.AllowAnyOrigin();
});

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();